Skip to content

http conn man: fix memory leak with watermark buffer#23401

Merged
KBaichoo merged 3 commits intoenvoyproxy:mainfrom
Hexta:fix-watermarkbuffer-memory-leak-with-internal-redirect
Oct 14, 2022
Merged

http conn man: fix memory leak with watermark buffer#23401
KBaichoo merged 3 commits intoenvoyproxy:mainfrom
Hexta:fix-watermarkbuffer-memory-leak-with-internal-redirect

Conversation

@Hexta
Copy link
Copy Markdown
Contributor

@Hexta Hexta commented Oct 7, 2022

Fix memory leak with stream recreated when watermark buffer tracking enabled.

Do not create a new memory account for the recreated stream in ConnectionManagerImpl::ActiveStream::recreateStream.
Re-use an account from the old stream.

Risk Level: low
Testing: integration

Fix memory leak with stream recreated when watermark buffer tracking enabled.

Call clearDownstream() method for the old stream's memory account inside
ConnectionManagerImpl::ActiveStream::recreateStream to unregister old
account before creating a new one.

Signed-off-by: Artur Malchanau <artur.molchanov@bolt.eu>
@repokitteh-read-only
Copy link
Copy Markdown

Hi @Hexta, welcome and thank you for your contribution.

We will try to review your Pull Request as quickly as possible.

In the meantime, please take a look at the contribution guidelines if you have not done so already.

🐱

Caused by: #23401 was opened by Hexta.

see: more, trace.

@RyanTheOptimist
Copy link
Copy Markdown
Contributor

/assign @KBaichoo

Copy link
Copy Markdown
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this! Few improvements I think we can make.

Comment thread source/common/http/conn_manager_impl.cc Outdated
// Make sure to not check for deferred close as we'll be immediately creating a new stream.
connection_manager_.doEndStream(*this, /*check_for_deferred_close*/ false);

auto oldAccount = response_encoder->getStream().account();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we follow style guide: https://google.github.io/styleguide/cppguide.html#Variable_Names for naming local variable

Comment thread source/common/http/conn_manager_impl.cc Outdated
if (oldAccount != nullptr) {
oldAccount->clearDownstream();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The slices in the request_data still are referring to the old account, we should have them transfered to refer to the account of the recreated stream (crediting the old account which will be destroyed at the end of this function)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, we can re-use the old account because the downstream connection is still the same.
WDYT?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I think that'd work and be simpler. We would need to modify ConnectionManagerImpl::newStream for the case there's an existing account associated which there will be if we're recreating the stream.

}

if (streamBufferAccounting()) {
EXPECT_EQ(buffer_factory_->numAccountsCreated(), 2);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we validate the transfer of bytes in request body so that we include them in our accounting? (possibly in another test, this one has no request body).

@KBaichoo
Copy link
Copy Markdown
Contributor

/wait

Keep the old memory account for the recreated stream to simplify logic.
Add an integration test for internal redirect with request body.

Signed-off-by: Artur Malchanau <artur.molchanov@bolt.eu>

Signed-off-by: Artur Malchanau <artur.molchanov@taxify.eu>
Copy link
Copy Markdown
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just minor changes, otherwise pending CI this looks good. Thanks for catching this.

default_request_headers_.setHost("handle.internal.redirect");
default_request_headers_.setMethod("POST");

const std::string& request_body = "foobarbizbaz";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldn't be a reference

}

TEST_P(Http2BufferWatermarksTest, AccountsAndInternalRedirectWithRequestBody) {
Http::TestResponseHeaderMapImpl redirect_response_{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: naming, should be redirect_response the _ suffix is reserved for object fields. Consider making const since it's not modified and shifting it down right where it's used.

Same with above test.

@KBaichoo
Copy link
Copy Markdown
Contributor

/wait

Signed-off-by: Artur Malchanau <artur.molchanov@bolt.eu>
@KBaichoo
Copy link
Copy Markdown
Contributor

/retest

@repokitteh-read-only
Copy link
Copy Markdown

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #23401 (comment) was created by @KBaichoo.

see: more, trace.

Copy link
Copy Markdown
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks!

@KBaichoo KBaichoo merged commit 0a195ac into envoyproxy:main Oct 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants